﻿
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using NPOI.HPSF;
using SiyinPractice.Application.Core;
using SiyinPractice.Domain.Core;
using SiyinPractice.Domain.FileByUploadAndDown;
using SiyinPractice.Framework.Mapper;
using SiyinPractice.Interface.FileByUploadAndDown;
using SiyinPractice.Shared.Core.Dto;
using SiyinPractice.Shared.Core.Exceptions;
using SiyinPractice.Shared.Core.Utility;
using SiyinPractice.Shared.FileByUploadAndDown.Dto.File;
using System.Linq.Expressions;
using System.Runtime.InteropServices;

namespace SiyinPractice.Application.FileByUploadAndDown
{
    public class FileUploadAndDownService : NamedEntityService<FileUploadAndDown, FileUploadAndDownDto, FileUploadAndDownSearchPagedDto, CreateFileUploadAndDownDto>, IFileUploadAndDownService
    {
        public FileUploadAndDownService(IEfRepository<FileUploadAndDown> repository, IObjectMapper objectMapper) : base(repository, objectMapper)
        {
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public override async Task<int> RemoveAsync(Guid id)
        {
            var entity = await Repository.FindAsync(id);
            Validate.Assert(entity == null, SiyinPracticeMessage.DELETE_NONEXIST);
            File.Delete(entity.FilePath);
            return await Repository.DeleteAsync(id);
        }
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="remarks"></param>
        /// <returns></returns>
        public async Task<int> UploadFile(IFormFile file, string remarks)
        {
            // 检查文件是否存在
            Validate.Assert(file == null || file.Length == 0, "文件不存在");

            // 生成唯一的文件名
            var fileName = DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.ToString("HHmmss") + "_" + file.FileName;

            var currentDatePath = "";
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                // 构建日期和时间子目录
                currentDatePath = Path.Combine("C:\\file", DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HH"));
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                currentDatePath = Path.Combine("/siyin/api/file", DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HH"));
            }
            else
            {
                Validate.Assert(true, "不支持的操作系统");
            }
            // 创建目录（如果不存在）
            Directory.CreateDirectory(currentDatePath);

            // 构建文件路径
            var filePath = Path.Combine(currentDatePath, fileName);

            // 保存文件到服务器
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                file.CopyTo(stream);
            }

            // 将文件信息保存到数据库
            var sysFile = new FileUploadAndDownDto
            {
                
                Id = Guid.NewGuid(),
                Name = file.FileName,
                CreateTime = DateTime.Now,
                Creator = Framework.Security.UserTokenService.GetUserToken()?.UserName,
                FileName = fileName,
                FileType = file.ContentType,
                Description = remarks,
                FilePath = filePath,
                DownloadCount = 0
            };
            Validate.Assert(sysFile == null, SiyinPracticeMessage.DTO_IS_NULL);
            var exits = await Repository.AnyAsync(x => x.Name == sysFile.FileName);
            Validate.Assert(exits, SiyinPracticeMessage.ENTITY_EXIST, sysFile.FileName);
            var entity = await MapToEntity(sysFile);

            return await Repository.InsertAsync(entity);
        }
        /// <summary>
        /// 更新下载次数
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<FileUploadAndDownDto> GetFlieByFileName(string fileName)
        {
            var entity =  Repository.Where(x => x.FileName.Contains(fileName)).OrderByDescending(x=>x.CreateTime).FirstOrDefault();
            Validate.Assert(entity == null, "文件名不存在", fileName);
            entity.DownloadCount++;
            await Repository.UpdateAsync(entity);
            // 根据文件信息构建文件的完整路径
            return await MapToEntityDto(entity);
        }

        public override async Task<PageModelDto<FileUploadAndDownDto>> GetPagedAsync(FileUploadAndDownSearchPagedDto search)
        {
            var whereExpression = BuildWhereExpression(ExpressionCreator.New<FileUploadAndDown>(), search);

            var total = await Repository.CountAsync(whereExpression);
            if (total == 0) return new PageModelDto<FileUploadAndDownDto>(search);

            var includeProperties = BuildIncludeProperties();

            var entities = Repository.Where(whereExpression, includeProperties)
                                     .OrderByDescending(x => x.CreateTime)
                                     .Skip(search.SkipRows())
                                     .Take(search.PageSize)
                                     .ToList();

            var entityDtos = await MapToEntityDto(entities);
            return new PageModelDto<FileUploadAndDownDto>(search, entityDtos, total);
        }
    }
}